package com.djf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.djf.entity.Order;
import com.djf.entity.User;
import com.djf.entity.UserDelivery;
import com.djf.mapper.OrderMapper;
import com.djf.mapper.UserDeliveryMapper;
import com.djf.mapper.UserMapper;
import com.djf.service.DataGeneratorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 数据生成服务实现类
 *
 * @author djf
 * @since 2025-01-22
 */
@Slf4j
@Service
public class DataGeneratorServiceImpl implements DataGeneratorService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserDeliveryMapper userDeliveryMapper;

    // 商品名称池
    private static final String[] PRODUCT_NAMES = {
            "iPhone 15 Pro Max", "MacBook Pro M3", "iPad Pro", "Apple Watch Series 9",
            "Samsung Galaxy S24", "华为Mate 60 Pro", "小米14 Pro", "OPPO Find X7",
            "vivo X100 Pro", "联想ThinkPad X1", "戴尔XPS 13", "华硕ROG游戏本",
            "索尼WH-1000XM5耳机", "Bose QuietComfort 45", "AirPods Pro 2",
            "Nintendo Switch OLED", "PlayStation 5", "Xbox Series X",
            "佳能EOS R5相机", "尼康Z9相机", "大疆Air 3无人机"
    };

    // 支付方式池
    private static final String[] PAYMENT_METHODS = {
            "支付宝", "微信支付", "银行卡", "花呗", "京东白条"
    };

    // 城市地址池
    private static final String[][] ADDRESSES = {
            {"北京市", "朝阳区", "建国路88号SOHO现代城"},
            {"上海市", "浦东新区", "陆家嘴环路1000号"},
            {"广州市", "天河区", "珠江新城花城大道85号"},
            {"深圳市", "南山区", "科技园南区深南大道9988号"},
            {"杭州市", "西湖区", "文三路259号昌地火炬大厦"},
            {"成都市", "锦江区", "红星路三段1号IFS国际金融中心"},
            {"武汉市", "江汉区", "中山大道818号平安大厦"},
            {"南京市", "鼓楼区", "中山路321号现代大厦"},
            {"西安市", "雁塔区", "高新四路15号"},
            {"重庆市", "渝中区", "解放碑步行街88号"}
    };

    // 快递公司池
    private static final String[] DELIVERY_COMPANIES = {
            "顺丰速运", "圆通速递", "中通快递", "申通快递", "韵达速递",
            "百世快递", "德邦快递", "京东物流", "菜鸟网络", "邮政EMS"
    };

    // 姓名池
    private static final String[] FIRST_NAMES = {
            "王", "李", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴",
            "徐", "孙", "胡", "朱", "高", "林", "何", "郭", "马", "罗"
    };

    private static final String[] LAST_NAMES = {
            "伟", "芳", "娜", "秀英", "敏", "静", "丽", "强", "磊", "军",
            "洋", "勇", "艳", "杰", "涛", "明", "超", "秀兰", "霞", "平",
            "刚", "桂英", "建华", "建国", "建军", "志强", "志明", "秀珍", "秀芳", "国强"
    };

    @Override
    @Transactional
    public List<User> generateUsers(int count) {
        List<User> users = new ArrayList<>();
        Random random = new Random();
        
        for (int i = 0; i < count; i++) {
            User user = new User();
            user.setUserName(generateRandomName());
            user.setPhone(generateRandomPhone());
            user.setEmail(generateRandomEmail());
            user.setGender(random.nextInt(3)); // 0-未知，1-男，2-女
            user.setBirthday(generateRandomBirthday());
            user.setStatus(1); // 启用状态
            user.setTenantId(1000L + random.nextInt(5)); // 租户ID 1000-1004
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setDeleted(0);
            
            users.add(user);
        }
        
        // 批量插入用户
        for (User user : users) {
            userMapper.insert(user);
        }
        
        log.info("成功生成 {} 个用户数据", count);
        return users;
    }

    @Override
    @Transactional
    public List<Order> generateOrders(int count, String startMonth, String endMonth) {
        List<Order> orders = new ArrayList<>();
        Random random = new Random();
        
        // 获取现有用户ID列表
        List<User> existingUsers = userMapper.selectList(new QueryWrapper<User>().eq("deleted", 0));
        if (existingUsers.isEmpty()) {
            throw new RuntimeException("没有可用的用户数据，请先生成用户数据");
        }
        
        List<Long> userIds = new ArrayList<>();
        for (User user : existingUsers) {
            userIds.add(user.getId());
        }
        
        // 解析月份范围
        LocalDateTime startTime = parseMonth(startMonth);
        LocalDateTime endTime = parseMonth(endMonth).plusMonths(1).minusSeconds(1);
        
        for (int i = 0; i < count; i++) {
            Order order = new Order();
            
            // 生成订单号
            String orderNo = generateOrderNo();
            order.setOrderNo(orderNo);
            
            // 随机选择用户
            Long userId = userIds.get(random.nextInt(userIds.size()));
            order.setUserId(userId);
            order.setTenantId(1000L + random.nextInt(5));
            
            // 随机选择商品
            String productName = PRODUCT_NAMES[random.nextInt(PRODUCT_NAMES.length)];
            order.setProductName(productName);
            
            // 生成价格和数量
            BigDecimal price = BigDecimal.valueOf(100 + random.nextInt(9900)).add(BigDecimal.valueOf(random.nextInt(100), 2));
            int quantity = 1 + random.nextInt(3);
            order.setProductPrice(price);
            order.setQuantity(quantity);
            order.setTotalAmount(price.multiply(BigDecimal.valueOf(quantity)));
            
            // 订单状态
            order.setOrderStatus(1 + random.nextInt(5)); // 1-5
            
            // 支付方式
            order.setPaymentMethod(PAYMENT_METHODS[random.nextInt(PAYMENT_METHODS.length)]);
            
            // 收货地址
            String[] address = ADDRESSES[random.nextInt(ADDRESSES.length)];
            order.setShippingAddress(address[0] + address[1] + address[2]);
            
            // 备注
            order.setRemark("测试订单数据" + (i + 1));
            
            // 时间
            LocalDateTime createTime = generateRandomTime(startTime, endTime);
            order.setCreateTime(createTime);
            order.setUpdateTime(createTime);
            order.setDeleted(0);
            
            orders.add(order);
        }
        
        // 批量插入订单
        for (Order order : orders) {
            orderMapper.insert(order);
        }
        
        log.info("成功生成 {} 个订单数据", count);
        return orders;
    }

    @Override
    @Transactional
    public List<UserDelivery> generateDeliveries(List<Order> orders) {
        List<UserDelivery> deliveries = new ArrayList<>();
        Random random = new Random();
        
        for (Order order : orders) {
            UserDelivery delivery = new UserDelivery();
            
            delivery.setUserId(order.getUserId());
            delivery.setOrderId(order.getId());
            delivery.setDeliveryNo(generateDeliveryNo());
            
            // 收货人信息
            delivery.setReceiverName(generateRandomName());
            delivery.setReceiverPhone(generateRandomPhone());
            
            // 地址信息
            String[] address = ADDRESSES[random.nextInt(ADDRESSES.length)];
            delivery.setProvince(address[0].replace("市", ""));
            delivery.setCity(address[1].replace("区", ""));
            delivery.setDistrict(address[1]);
            delivery.setDeliveryAddress(address[0] + address[1] + address[2]);
            
            // 配送状态
            delivery.setDeliveryStatus(1 + random.nextInt(4)); // 1-4
            
            // 快递信息
            delivery.setCourierName(generateRandomName());
            delivery.setCourierPhone(generateRandomPhone());
            delivery.setDeliveryCompany(DELIVERY_COMPANIES[random.nextInt(DELIVERY_COMPANIES.length)]);
            delivery.setTrackingNumber(generateTrackingNumber());
            
            // 时间信息
            LocalDateTime orderTime = order.getCreateTime();
            delivery.setEstimatedTime(orderTime.plusDays(1 + random.nextInt(3)));
            if (delivery.getDeliveryStatus() >= 3) {
                delivery.setActualTime(orderTime.plusDays(1 + random.nextInt(2)));
            }
            
            delivery.setRemark("配送备注信息");
            delivery.setCreateTime(orderTime);
            delivery.setUpdateTime(orderTime);
            delivery.setDeleted(0);
            
            deliveries.add(delivery);
        }
        
        // 批量插入配送数据
        for (UserDelivery delivery : deliveries) {
            userDeliveryMapper.insert(delivery);
        }
        
        log.info("成功生成 {} 个配送数据", deliveries.size());
        return deliveries;
    }

    @Override
    @Transactional
    public GenerateResult generateCompleteTestData(int userCount, int orderCount, String startMonth, String endMonth) {
        try {
            // 1. 生成用户数据
            List<User> users = generateUsers(userCount);
            
            // 2. 生成订单数据
            List<Order> orders = generateOrders(orderCount, startMonth, endMonth);
            
            // 3. 生成配送数据
            List<UserDelivery> deliveries = generateDeliveries(orders);
            
            String message = String.format("成功生成测试数据：用户 %d 个，订单 %d 个，配送 %d 个", 
                    users.size(), orders.size(), deliveries.size());
            
            return new GenerateResult(users.size(), orders.size(), deliveries.size(), message);
            
        } catch (Exception e) {
            log.error("生成测试数据失败", e);
            throw new RuntimeException("生成测试数据失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public void clearAllTestData() {
        // 清空配送数据
        userDeliveryMapper.delete(new QueryWrapper<>());
        
        // 清空订单数据
        orderMapper.delete(new QueryWrapper<>());
        
        // 清空用户数据
        userMapper.delete(new QueryWrapper<>());
        
        log.info("已清空所有测试数据");
    }

    // 辅助方法
    private String generateRandomName() {
        Random random = new Random();
        return FIRST_NAMES[random.nextInt(FIRST_NAMES.length)] + 
               LAST_NAMES[random.nextInt(LAST_NAMES.length)];
    }

    private String generateRandomPhone() {
        Random random = new Random();
        return "1" + (3 + random.nextInt(6)) + String.format("%09d", random.nextInt(1000000000));
    }

    private String generateRandomEmail() {
        Random random = new Random();
        String[] domains = {"qq.com", "163.com", "gmail.com", "126.com", "sina.com"};
        return "user" + random.nextInt(100000) + "@" + domains[random.nextInt(domains.length)];
    }

    private LocalDate generateRandomBirthday() {
        Random random = new Random();
        int year = 1970 + random.nextInt(35); // 1970-2004
        int month = 1 + random.nextInt(12);
        int day = 1 + random.nextInt(28);
        return LocalDate.of(year, month, day);
    }

    private String generateOrderNo() {
        return "ORD" + System.currentTimeMillis() + String.format("%03d", new Random().nextInt(1000));
    }

    private String generateDeliveryNo() {
        return "DEL" + System.currentTimeMillis() + String.format("%03d", new Random().nextInt(1000));
    }

    private String generateTrackingNumber() {
        return "TRK" + System.currentTimeMillis() + String.format("%04d", new Random().nextInt(10000));
    }

    private LocalDateTime parseMonth(String month) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
        return LocalDate.parse(month, formatter).atStartOfDay();
    }

    private LocalDateTime generateRandomTime(LocalDateTime start, LocalDateTime end) {
        long startEpoch = start.toEpochSecond(java.time.ZoneOffset.UTC);
        long endEpoch = end.toEpochSecond(java.time.ZoneOffset.UTC);
        long randomEpoch = ThreadLocalRandom.current().nextLong(startEpoch, endEpoch);
        return LocalDateTime.ofEpochSecond(randomEpoch, 0, java.time.ZoneOffset.UTC);
    }
}